#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include "ngx_c_conf.h"
#include "ngx_func.h"
#include "ngx_macro.h"
#include "ngx_global.h"

/*
    守护进程初始化
    返回值：
        失败：-1
        子进程：0
        父进程：1
*/
int ngx_daemon()
{
    switch (fork())
    {
    case -1:
        // 创建子进程失败
        ngx_log_error_core(NGX_LOG_EMERG, errno, "ngx_daemon fork failed!");
        return -1;
    case 0:
        // 子进程
        break;
    default:
        // 父进程
        return 1;
    }

    // 子进程会执行以下的代码
    ngx_parent = ngx_pid; // ngx_pid是原来父进程的id
    ngx_pid = getpid(); // ngx_pid设置为当前进程的id
    if (setsid() == -1)
    {// 脱离终端，跟此子进程无关
        ngx_log_error_core(NGX_LOG_EMERG, errno, "ngx_daemon setsid failed!");
        return -1;
    }
    umask(0);
    int fd = open("/dev/null", O_RDWR);
    if (fd == -1)
    {// 打开空设备文件失败
        ngx_log_error_core(NGX_LOG_EMERG, errno, "ngx_daemon open /dev.null failed!");
        return -1;
    }
    if (dup2(fd, STDIN_FILENO) == -1)
    {
        ngx_log_error_core(NGX_LOG_EMERG, errno, "ngx_daemon dup2(fd, STDIN_FILENO) failed!");
        return -1;
    }
    if (dup2(fd, STDOUT_FILENO) == -1)
    {
        ngx_log_error_core(NGX_LOG_EMERG, errno, "ngx_daemon dup2(fd, STDOUT_FILENO) failed!");
        return -1;
    }
    if (dup2(fd, STDERR_FILENO) == -1)
    {
        ngx_log_error_core(NGX_LOG_EMERG, errno, "ngx_daemon dup2(fd, STDERR_FILENO) failed!");
        return -1;
    }
    if (fd > STDERR_FILENO)
    {// STDERR_FILENO应该是3， fd应该是2，会成立
        if (close(fd) == -1)
        {
            ngx_log_error_core(NGX_LOG_EMERG, errno, "ngx_daemon close(fd) failed!");
            return -1;
        }
    }
    return 0; // 子进程成功返回0
}
